# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# pyojo                                           Copyright (c) 2011 nabla.net
# ----------------------------------------------------------------------------
""" Base classes for dijit objects.
"""

from pyojo.func import Error
from pyojo.js.code import js_code, js_check, Object, Code, domNode
from pyojo.js.dojo._base import Dojo



class Dijit(Dojo):
    """ Base class for all Dijit widgets.
    """
    require = ["dojo/ready"]
    local = False
    registered = False
    startup = True
    loc_pre = ""
    loc = ""
    loc_post = ""

            
    def __init__(self, var=None, registered=True, **member):
        """ Create a new Dijit widget.
        
        Any parameter will be passed to the Javascript constructor, except 
        *var* and *registered*.
            
        :param var:
           name of the Javascript variable, or True to generate a unique name. 
           Default is None, to indicate no name.
               
        :param registered: pass a id attribute to the constructor.
        :type registered: boolean
            
        :param ID: a special member passed as the last parameter, represents 
        the target DOM node.
            
               
        """
        self.ID = self.__class__.__name__ + str(id(self))
        if var is True:
            var = self.ID
        if var is not None:
            if type(var)!=type(""):
                raise Error("Object var name must be a string.")
        self.var = var
        self.domNode = domNode(self.var)
        self.member = {}
        if registered and var is not None:
            self.member["id"] = var
        self.member.update(member)    
        self.init()
    
    
    def __setitem__(self, key, value):
        self.member.__setitem__(key, value)

    def __getitem__(self, key):
        return self.member.__getitem__(key)

    def __delitem__(self, key):
        return self.member.__delitem__(key)
    
    def init(self): pass


    def new(self):
        """ Get the JavaScript constructor code.
        
        :returns: LOC
        """
        ID = self.member.get("ID")
        if ID is True: 
            ID = self.ID   
        if ID is None: par = ""
        else: 
            del self.member["ID"]
            par=", '%s'" % ID 
        
        return "new %s(%s%s)" % (self.__class__.__name__, 
                                     js_code(self.member), par)
        

    def declare(self):
        """ Assign this object to a variable.
        
        :returns: LOC
        """
        loc = "var " if self.local else ""
        var = "" if self.var is None else loc + "%s = " % self.var
        return var + self.new() + ";"



    def code(self): #, catch=False, start=True, place=None
        """ Get the code.
        
        :returns: LOC
        """
        loc = self.loc_pre
        loc += self.declare()
        loc += self.loc    
        loc += self.loc_post
        
            
        if self.startup and self.var is not None: 
            loc += "%s.startup();" % (self.var)
            
        if self.registered:
            return js_check(self.var, loc)
        else: 
            return loc
    
    def __repr__(self):
        return "<Dijit %s '%s' %s>" % (self.__class__.__name__, 
                                       self.var, self.member)

    
    def add(self, parent):
        """ Adds this dijit calling tghe parents addChild
        """
        return self.get_block(parent, "addChild", self.new())
    
    #def methods(self, parent, **methods):
    #    for method, code in methods.iteritems():
    #        yield Dojo("%s.%s(%s);" % (parent, method, self.new())
    #                ).requires(*self.get_requires())

    def call_method(self, method, parameter=""):
        """ Adds a call to a method to the code.
        """
        self.loc_post += "%s.%s(%s);" % (self.var, method, parameter)

    def call_method_of(self, target, method):
        """ Adds a call to a method from other object to the code.
        """
        loc = "%s.%s(%s);" % (target, method, self.var)
        self.loc_post += loc


    def place(self, target):
        """ Place this dijit at other object.
        """
        self.call_method("placeAt", "%s" % js_code(target))

    def resize(self):
        self.call_method("resize")
    
    def show(self):
        self.call_method("show")
    
    def hide(self):
        self.call_method("hide")
    
    
    
    
    def method(self, name):
        print "method %s" % name
        return Code("%s.%s();" % (self.var, name))
    
         

    
    def set(self, attr, value):
        """ Sets a property.
        """
        print "%s.set(%s, %s)" %  (self.var, attr, value)
        return Code("%s.set('%s', '%s');" % (self.var, attr, value))


    
    def connect(self, **events):
        """ Allows one function to be called when any other is called.
        
        :param event: the name of the method/event to be listened for.
        """ 
        loc = ""
        for event, func in events.iteritems():
            loc += "%s.connect(%s, '%s', %s);" % (self.var, 
                                                  self.var, event, func)
        #context, method, dontFix
        return self.code_add(loc)
    
    




class Registry(Dojo):
    """ Stores a collection of all the dijit widgets within a page.
    
    """
    require = ["dojo/ready", "dijit/registry"]
    

    @staticmethod
    def byId(name):
        """ Retrieve a widget from the registry using a widget ID.
        """
        return Registry("registry.byId('%s');" % (name))

    @staticmethod
    def byNode(domNode):
        """ Retrieve a widget from the registry using its DOM node
        """
        return Registry("registry.byId('%s');" % (domNode))

    @staticmethod
    def getEnclosingWidget(domNode):
        """ Find the nearest enclosing widget for a DOM node
        """
        return Registry("registry.getEnclosingWidget('%s');" % (domNode))
  
    @staticmethod
    def toArray():
        """ Get an Array to iterate over the entire registry.
        """
        return Registry("registry.toArray();")


class WidgetSet(Dojo, Object):
    """ A collection of Dijit widgets.
    """
    require = ["dojo/ready", "dijit/WidgetSet"]

# ----------------------------------------------------------------------------
